package com.blackline.auto.Match;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.TimeUnit;
import org.apache.log4j.Logger;
import org.junit.*;
import static org.junit.Assert.*;
import org.openqa.selenium.*;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxProfile;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.support.ui.Select;

import com.blackline.parameters.*;
import com.blackline.auto.common.CommonMethods;
import com.blackline.declareUI.UI;

/**
 * @author XBO
 * @version Feb, 2013
 * <p>The smoke test to Match module.
 */
public class Match_smoketest {
	private WebDriver driver;
	private StringBuffer verificationErrors = new StringBuffer();
	private static Logger logger=Logger.getLogger(Match_smoketest.class);
	UI UI=new UI();
	Parameters parameters;
	@Before
	public void setUp() throws Exception {
		FirefoxProfile profile=new FirefoxProfile();
		profile.setEnableNativeEvents(true);
		parameters=new Parameters("parameters.xml");

		driver = new FirefoxDriver();
		driver.manage().window().maximize();
		driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
		UI.declareAllUI(driver);
	}

	@Test
	public void Matchsmoketest() throws Exception {
		TestData testdata = new TestData("TestData/Match_smoketest.xml");
		Actions action = new Actions(driver);
		
		//=======================Data Preparation=======================//

				CommonMethods cm = new CommonMethods();
				String dateString = cm.dateString();
				
				//The last field of following inputText is "8900"
				String inputText = "4000	"+ dateString +"									B2013022602	B2013022602	A	Asset	TRUE	TRUE	USD	USD	1/31/2011			8900";
				logger.info("The inputText for " + testdata.getInput("accountFile") + " is: " + inputText);
				//Create Account.Import.text file and write inputText into it.
				cm.createFile(("TestData\\" + testdata.getInput("accountFile")), inputText);
				
				//The absolute path of the Account_Import.Auto.Match01.txt file.
				String accountFilePath = System.getProperty("user.dir") + "\\TestData\\" + testdata.getInput("accountFile");
				logger.info("Location of " + testdata.getInput("accountFile") + " is: " + accountFilePath);
				
				//The absolute path of the Match_smoketest_TestGDS.xls file.
				String ds1filePath = System.getProperty("user.dir") + "\\TestData\\" + testdata.getInput("datasourceFile1");
				logger.info("Location of " + testdata.getInput("datasourceFile1") + " is: " + ds1filePath);

				//The absolute path of the Match_smoketest_TestLDS.xls file.
				String ds2filePath = System.getProperty("user.dir") + "\\TestData\\" + testdata.getInput("datasourceFile2");
				logger.info("Location of " + testdata.getInput("datasourceFile2") + " is: " + ds2filePath);
				
				//Account file without extension: Account_Import.Auto.Match01.txt > Account_Import.Auto.Match01
				String inputFileNoExtension = testdata.getInput("accountFile").substring(0, testdata.getInput("accountFile").length()-4);
				logger.info("Account file without extension is: " + inputFileNoExtension);
			
			//=======================Import Account=======================//
				//Log into system
				UI.LogonPage.Login(driver, parameters.urlDev2, parameters.getLogonID("admin"), parameters.getPassword("admin"));
				UI.NavigationMenu.IMPORTS.click();
				UI.NavigationMenu.Import_Data.click();
				UI.page.selectOptionForDropdownList(UI.ImportData.Import_dropDownList, "Accounts");
				UI.ImportData.Document_textField.sendKeys(accountFilePath);
				UI.ImportData.Import_button.click();
				
				//Verify import successfully.
				
				if (UI.ImportData.OperationResult.getText().contains("Succeed"))
				{
					logger.info("[Pass!] The importing file operation succeeded!");
				}
				else
				{
					logger.error("[Fail!] The importing file operation failed!");
					verificationErrors.append("[Fail!] The importing file operation failed!");
				}
				
				UI.SessionMenu.LogOut.click();
				
			//======================Import 2 Data Sources=====================//
				UI.LogonPage.Login(driver, parameters.urlDev2, parameters.getLogonID("preparer"), parameters.getPassword("preparer"));
				UI.NavigationMenu.MATCH.click();
				UI.NavigationMenu.Create_Data_Source.click();
				
				
				
				//Import DS file
				UI.CreateDataSource.Import_File_textField.sendKeys(ds1filePath);//Select DS file: Match_smoketest_TestGDS.xls
				UI.CreateDataSource.Load_icon.click();
				new Select(UI.CreateDataSource.Work_Sheets_dropDownList).selectByVisibleText(testdata.getInput("sheetName"));
				
				UI.CreateDataSource.Preview_icon.click();
				UI.CreateDataSource.Create_Data_Source_button.click();
				
				
				//Input texts into Name text box. To do this, need switch to the Name iFrame first.
//				String nameiFrame = UI.CreateDataSourceSubpage.Name_iframe.getAttribute("name");
				driver.switchTo().frame(UI.CreateDataSourceSubpage.Name_iframe);
				
				
				
				
				
				driver.switchTo().defaultContent();
				UI.CreateDataSource.Maximize_Window_icon.click();
				driver.switchTo().frame(UI.CreateDataSourceSubpage.Name_iframe);
				
				
				
				
				//Enter a valid data source name {such as: "TestG"}.
				UI.CreateDataSourceSubpage.Name_textField.sendKeys(testdata.getInput("datasourceName1") + dateString);
				Thread.sleep(5000);
				//Click on the amount type column {select "Amount" and "ReverseAmount" columns for "TestG"}.
				UI.CreateDataSourceSubpage.selectItemsFromTable(driver, "ReverseAmount", "Amount");
				
				UI.CreateDataSourceSubpage.Edit_Selected_button.click();
				
				//Select "Money" from "Data Type" drop down list.
				UI.CreateDataSourceSubpage.Amount_cellInEditMode.click();
				logger.info("Clicked 'Amount' cell");
				UI.CreateDataSourceSubpage.Amount_DataType_inEditMode.sendKeys(testdata.getInput("dataType"));
				logger.info("Selected 'Money' for 'Amount'");
				UI.CreateDataSourceSubpage.ReverseAmount_DataType_inEditMode.sendKeys(testdata.getInput("dataType"));
				logger.info("Selected 'Money' for 'ReverseAmount'");

				UI.CreateDataSourceSubpage.Update_button.click();
				
				
				driver.switchTo().defaultContent();
				UI.CreateDataSource.Restore_Window_icon.click();
				driver.switchTo().frame(UI.CreateDataSourceSubpage.Name_iframe);
				
				UI.CreateDataSourceSubpage.Save_button.click();
				
				
				//Switch back to default content
				driver.switchTo().defaultContent();
				logger.info("Current page title: " + driver.getTitle());
				Thread.sleep(5000);
				
				//Click ">>Import All" button.
				UI.CreateDataSource.Import_All_button.click();
				
				//Verify the DS(TestG) can be imported successfully.
				Thread.sleep(5000);
			
				if (UI.CreateDataSource.Import_Success_text.getText().contains("uccess"))
				{
					logger.info("[Pass!] Data source imported Successfully");
				}
				else
				{
					logger.error("[Fail!] Data source imported failed.");
					verificationErrors.append("[Fail!] Data source imported failed.");
					
				}
				
				UI.CreateDataSource.Replace_icon.click();
				Thread.sleep(5000);
				//Choose an import DS file {such as : D:\BlackLineQTP\Base\TestLDS}.
				//Import DS file
				UI.CreateDataSource.Import_File_textField.sendKeys(ds2filePath);//Select DS file: Match_smoketest_TestLDS.xls
				Thread.sleep(5000);
				UI.CreateDataSource.Load_icon.click();
				Thread.sleep(5000);
				new Select(UI.CreateDataSource.Work_Sheets_dropDownList).selectByVisibleText(testdata.getInput("sheetName"));
				Thread.sleep(5000);
				
				UI.CreateDataSource.Preview_icon.click();
				Thread.sleep(5000);
				UI.CreateDataSource.Create_Data_Source_button.click();
				Thread.sleep(5000);
				//Input texts into Name text box. To do this, need switch to the Name iFrame first.
				driver.switchTo().frame(UI.CreateDataSourceSubpage.Name_iframe);
				Thread.sleep(5000);
				
				driver.switchTo().defaultContent();
				UI.CreateDataSource.Maximize_Window_icon.click();
				driver.switchTo().frame(UI.CreateDataSourceSubpage.Name_iframe);
				Thread.sleep(5000);
				
				//Enter a valid data source name {such as: "TestL"}.
				UI.CreateDataSourceSubpage.Name_textField.sendKeys(testdata.getInput("datasourceName2") + dateString);
				Thread.sleep(5000);
				//Click on the amount type column {select "CheckDollarAmount" for "TestL"}.
				UI.CreateDataSourceSubpage.selectItemsFromTable(driver, "CheckDollarAmount");
				Thread.sleep(5000);
				UI.CreateDataSourceSubpage.Edit_Selected_button.click();
				Thread.sleep(5000);
				//Select "Money" from "Data Type" drop down list.
				UI.CreateDataSourceSubpage.CheckDollarAmount_DataType_inEditMode.sendKeys(testdata.getInput("dataType"));				
				UI.CreateDataSourceSubpage.Update_button.click();
				Thread.sleep(5000);
				
				driver.switchTo().defaultContent();
				UI.CreateDataSource.Restore_Window_icon.click();
				driver.switchTo().frame(UI.CreateDataSourceSubpage.Name_iframe);
				
				
				UI.CreateDataSourceSubpage.Save_button.click();//!!!!!!!!!!!!!!Strange, can't find this Save button now!!!!
				Thread.sleep(5000);
				
				//Switch back to default content
				driver.switchTo().defaultContent();
				
				//Click ">>Import All" button.
				UI.CreateDataSource.Import_All_button.click();
				
				//Verify the DS(TestG) can be imported successfully.
				Thread.sleep(5000);
				if (UI.CreateDataSource.Import_Success_text.getText().contains("uccess"))
				{
					logger.info("[Pass!] Data source imported Successfully");
				}
				else
				{
					logger.error("[Fail!] Data source imported failed.");
					verificationErrors.append("[Fail!] Data source imported failed.");
				}
				
				
			//======================Add Match Set=====================//
				UI.NavigationMenu.REPORTS.click();
				UI.NavigationMenu.MATCH.click();
				UI.NavigationMenu.Match_Sets.click();
				UI.MatchSets.Add_New_Adhoc_Match_Set_button.click();
				
				//Fill in "Match Set Name" field with valid data, such as: {testm01}
				UI.MatchSetDetails_new.Match_Set_Name_textField.sendKeys(testdata.getInput("matchSetName1")+dateString);
				
				//Input texts into Description text box. To do this, need switch to the Description iFrame first.
				String idDescIframe = UI.MatchSetDetails_new.Description_iframe.getAttribute("id");
				driver.switchTo().frame(idDescIframe);
				UI.MatchSetDetails_new.Description_textBox.sendKeys(testdata.getInput("matchsetDesc"));
				//Switch back to default content
				driver.switchTo().defaultContent();
				
				
				//Select "Blackline International" as the Entity.
				UI.MatchSetDetails_new.Entity_downArrow.click();
				UI.MatchSetDetails_new.Blackline_International_node.click();
				
				
				//Select an account
				UI.MatchSetDetails_new.accountAddingIcon.click();
				
				//Select account. To do this, need switch to the popup iFrame first.
				driver.switchTo().frame(UI.SelectItemAccount.popup_iFrame);
				UI.SelectItemAccount.firstAccountCheckBox.click();				
				UI.SelectItemAccount.Select_button.click();
				
				//Switch back to default content
				driver.switchTo().defaultContent();
				
				//Select {TestG} from first data source drop down list.
				UI.page.selectOptionForDropdownList(UI.MatchSetDetails_new.Data_Source_1_dropdownList, testdata.getInput("datasourceName1") + dateString);
//				UI.page.selectOptionForDropdownList(UI.MatchSetDetails_new.Data_Source_1_dropdownList, testdata.getInput("datasourceName1")); //Don't use this in final
				Thread.sleep(10000);
				UI.MatchSetDetails_new.Dispaly_Fields_1_link.click();
				

				//Switch to "Configure grid display fields" iframe
				driver.switchTo().frame(UI.ConfigureGridDisplayFields.popup_iFrame);
				
				//Click the first item, then press Shift, click the End key, to select all items.
				UI.ConfigureGridDisplayFields.firstSelection_inAvailableFields.click();

				action.keyDown(Keys.SHIFT).sendKeys(Keys.END).keyUp(Keys.SHIFT).perform();
		        
		        //Click Add Item icon
		        UI.ConfigureGridDisplayFields.Add_Item_iconInAvailableFields.click();
		        UI.page.selectOptionForDropdownList(UI.ConfigureGridDisplayFields.Subtotal_Fields_dropDownList, testdata.getInput("subtotalField1"));
		        UI.ConfigureGridDisplayFields.Save_button.click();
				
		        //Click "Supporting Items" link for "TestG".
		        UI.MatchSetDetails_new.Supporting_Items_1_link.click();
		        
		        //Switch to the popup iFrame first.
				driver.switchTo().frame(UI.ConfigureSupportingItems.popup_iFrame);
				UI.ConfigureSupportingItems.Save_button.click();
				//Switch back to default content
				driver.switchTo().defaultContent();
				
				
				
				
				//Select {TestL} from first data source drop down list.
				UI.page.selectOptionForDropdownList(UI.MatchSetDetails_new.Data_Source_2_dropdownList, testdata.getInput("datasourceName2") + dateString);
//				UI.page.selectOptionForDropdownList(UI.MatchSetDetails_new.Data_Source_2_dropdownList, testdata.getInput("datasourceName2"));//Don't use this in final
				Thread.sleep(10000);
				UI.MatchSetDetails_new.Dispaly_Fields_2_link.click();
				

				//Switch to "Configure grid display fields" iframe
				driver.switchTo().frame(UI.ConfigureGridDisplayFields.popup_iFrame);
				
				//Click the first item, then press Shift, click the End key, to select all items.
				UI.ConfigureGridDisplayFields.firstSelection_inAvailableFields.click();
				action.keyDown(Keys.SHIFT).sendKeys(Keys.END).keyUp(Keys.SHIFT).perform();
		        
		        //Click Add Item icon
		        UI.ConfigureGridDisplayFields.Add_Item_iconInAvailableFields.click();
		        UI.page.selectOptionForDropdownList(UI.ConfigureGridDisplayFields.Subtotal_Fields_dropDownList, testdata.getInput("subtotalField2"));
		        UI.ConfigureGridDisplayFields.Save_button.click();
				Thread.sleep(10000);//If don't sleep, sometimes can't find Supporting_Item_2_link;
				
		        //Click "Supporting Items" link for "TestG".
		        UI.MatchSetDetails_new.Supporting_Items_2_link.click();
		        
		        //Switch to the popup iFrame first.
				driver.switchTo().frame(UI.ConfigureSupportingItems.popup_iFrame);
				UI.ConfigureSupportingItems.Save_button.click();
				//Switch back to default content
				driver.switchTo().defaultContent();
				
				
				
			//Add pass rule
				//The "Unmatched Transactions" button is available.
				if(UI.MatchSetDetails_new.Unmatched_Transactions_button.isEnabled())
				{
					logger.info("[Pass!] Unmatched Transactions button is enabled.");
				}
				else
				{
					logger.error("[Fail!] Unmatched Transactions button is NOT enabled.");
					verificationErrors.append("[Fail!] Unmatched Transactions button is NOT enabled.");
				}
				
				//Check "Allow preparer to suspend transactions." check box.
				UI.MatchSetDetails_new.Allow_preparer_to_suspend_transactions_checkbox.click();
				UI.MatchSetDetails_new.Allow_preparer_to_upload_transactions_checkbox.click();
				
				UI.MatchSetDetails_new.Add_linkUnderPassRulesAutoSuggested.click();
				Thread.sleep(10000);
		
				//Fill in "Pass Rule Name" field with valid data, such as {PR01}
				UI.PassRuleDetails.Pass_Rule_Name_textField.sendKeys(testdata.getInput("passRuleName"));
				
				//Switch to the Description iFrame first.
				driver.switchTo().frame(UI.PassRuleDetails.Description_iframe);
				UI.PassRuleDetails.Description_textBox.sendKeys(testdata.getInput("passRuleDescription"));
				//Switch back to default content
				driver.switchTo().defaultContent();
				
				//Select mapping for the pass rule. {Select "Amount" from "TestG" drop down list, select "CheckDollarAmount" from "TestL" drop down list}
				UI.page.selectOptionForDropdownList(UI.PassRuleDetails.Mapping_1_dropdownlist, testdata.getInput("subtotalField1"));
				UI.page.selectOptionForDropdownList(UI.PassRuleDetails.Mapping_2_dropdownlist, testdata.getInput("subtotalField2"));
				
				UI.PassRuleDetails.Save_button.click();
				
				//Verify the new pass rule {PR01} can be listed on Match Set Details.
				if (UI.MatchSetDetails_new.passRule1inRassRulesTable != null)
				{
					logger.info("[Pass!] Pass rule '" + testdata.getInput("passRuleName") + "' is added.");
				}
				else
				{
					logger.error("[Fail!] Pass rule '" + testdata.getInput("passRuleName") + "' is NOT added.");
					verificationErrors.append("[Fail!] Pass rule '" + testdata.getInput("passRuleName") + "' is NOT added.");
				}
					
				//==================================================================================================================//
				//The following inherit from old yellow cells. Note: they use "MatchSetDetails_Edit" instead of "MatchSetDetails_new".
				//Can consider to replace them, or merge the two pages in future.
				//==================================================================================================================//
				
				//Click "Run Matching Engine" button.
				UI.MatchSetDetails_edit.Matching_Engine_button.click();
				UI.MatchSetDetails_edit.Run_Matching_Engine_inDropdownList.click();
				
				String result = UI.MatchSetDetails_edit.Operation_Result_text.getText();
				if (result.contains("success"))
				{
					logger.info("[Pass!] Matching engine successfully scheduled.");
				}
				else
				{
					logger.error("[Failed!] Matching engine was FAILED to schedule.");
					verificationErrors.append("[Failed!] Matching engine was FAILED to schedule.");
				}
				
				//Click Match Engine.
				UI.MatchSetDetails_edit.Matching_Engine_button.click();
				UI.MatchSetDetails_edit.View_Matching_Engine_Status_inDropdownList.click();
				
				//Input match set name {testm01} and click apply link.
				UI.JobStatus.Name_ofSearchedResult.sendKeys(testdata.getInput("matchSetName1")+dateString);
				UI.JobStatus.Name_ofSearchedResult.sendKeys(Keys.ENTER);
				
				for (int i=0; i < 20; i++)
				{
					Thread.sleep(15000);
					String status = UI.JobStatus.Status_ofSearchedResult.getText();
					logger.info("The current status of searched result is: " + status);
					if (!status.contains("uccess"))
					{
						i++;
						logger.info("Will wait for another 15 seconds to check status again.");
						UI.JobStatus.Refresh_button.click();
					}
					else
					{
						i = 20;
					}
				}

				UI.NavigationMenu.REPORTS.click();
				UI.NavigationMenu.MATCH.click();
				UI.NavigationMenu.Matched_Transactions.click();
				
				//Filter the match set
				UI.MatchedTransactions.Match_Set_textField.sendKeys(testdata.getInput("matchSetName1")+dateString);//!!Use this for final
				//UI.MatchedTransactions.Match_Set_textField.sendKeys("testMatchSet0120130305-09-30-59");
				UI.MatchedTransactions.Apply_link.click();
				
				
				UI.MatchedTransactions.Automatic_linkOf1stSearchResult.click();
				
				//Check the total number of results
				int number1 = Integer.parseInt(UI.AutomaticMatches.totalNumberOfResults.getText());
				logger.info("Total number of results is: " + number1);
				
				//Select the checkbox for 1st item.
				UI.AutomaticMatches.checkboxOf1stItem.click();
				UI.AutomaticMatches.Unmatched_button.click();
				Thread.sleep(5000);
				driver.navigate().refresh();
				
				//Check the total number deduct one.
				int number2 = Integer.parseInt(UI.AutomaticMatches.totalNumberOfResults.getText());
				
				if (number1==(number2+1))
				{
				logger.info("[Pass!] The total number has subtracted 1.");
				}
				else
				{
					logger.error("[Fail!] The total number doesn't deduct 1.");
					verificationErrors.append("[Fail!] The total number doesn't deduct 1.");
				}
//				
			
	}

	@After
	public void tearDown() throws Exception {
		CommonMethods.takeScreenShot(this.getClass(), driver);
		driver.close();
 		driver.quit();
		String verificationErrorString = verificationErrors.toString();
		if (!"".equals(verificationErrorString)) {
			fail(verificationErrorString);
		}
	}
}
